package mathive.client;

import java.util.Date;

import com.google.gwt.core.client.GWT;
import com.google.gwt.user.client.Cookies;
import com.google.gwt.user.client.DOM;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.gwt.user.client.ui.Label;

public class UserHandler {
	private static final UserServiceAsync SERVICE = GWT.create(UserService.class);
	
	public static UserHandler singleton;
	
	private LoginSidebar loginbar;
	
	private String sessionID = null;
	
	private ClientUser user = null;
	
	private UserHandler() {
		
	}
	
	public static void initialize() {
		singleton = new UserHandler();
	}
	
	private void checkCookies() {
		sessionID = Cookies.getCookie("sid");
//		loginbar.update("sess: " + sessionID);
		if (sessionID != null) {
//			loginbar.update("update1");
			SERVICE.isOnline(
					sessionID,
					new IsOnlineResponse());
		} else {
			sessionID = null;
			loginbar.update("update2");
		}
	}
	
	public void setLoginbar(LoginSidebar loginsidebar) {
		loginbar = loginsidebar;
		checkCookies();
//		loginbar.update("update");
	}
	
	public boolean isOnline() {
		if (user != null) {
			return true;
		} else {
			return false;
		}
	}
	
	public boolean isAdmin() {
		if (user.getUsertype() == ClientUser.ADMIN) {
			return true;
		} else {
			return false;
		}
	}
	
	public boolean isTestUser() {
		if (user.getUsertype() == ClientUser.TEST_USER || user.getUsertype() == ClientUser.ADMIN) {
			return true;
		} else {
			return false;
		}
	}
	
	public void addScore(int score) {
		SERVICE.addScore(
				sessionID,
				score,
				new AddScoreResponse());
	}
	
	public String getUsername() {
		return user.getUsername();
	}
	
	public String getSessionID() {
		return sessionID;
	}
	
	public void login(String username, String password) {
		SERVICE.loginToServer(
				username,
				password,
				new LoginResponse());
	}
	
	public void logout() {
		SERVICE.logoutFromServer(
				sessionID,
				new LogoutResponse());
	}
	
	private class LoginResponse implements AsyncCallback<String> {
		@Override
		public void onFailure(Throwable caught) {
		}

		@Override
		public void onSuccess(String result) {
			sessionID = result;
		    final long DURATION = 1000 * 60 * 60 * 24 * 14; //duration remembering login. 2 weeks here.
		    Date expires = new Date(System.currentTimeMillis() + DURATION);
		    Cookies.setCookie("sid", sessionID, expires, null, "/", false);
		    
		    SERVICE.getUser(
					sessionID,
					new GetUserResponse());
		}
	}
	
	private class IsOnlineResponse implements AsyncCallback<Boolean> {
		@Override
		public void onFailure(Throwable caught) {
		}

		@Override
		public void onSuccess(Boolean result) {
			if (result.booleanValue()) {
				loginbar.update(sessionID);
				SERVICE.getUser(
						sessionID,
						new GetUserResponse());
			} else {
				sessionID = null;
				loginbar.update("fail: ");
			}
		}
	}
	
	private class LogoutResponse implements AsyncCallback<Boolean> {
		@Override
		public void onFailure(Throwable caught) {
		}

		@Override
		public void onSuccess(Boolean result) {
			
			if (result.booleanValue()) {
				user = null;
				sessionID = null;
				Cookies.removeCookie("sid");
				loginbar.update(sessionID);
				PanelHandler.showHome();
			} else {
				
			}
		}
	}
	
	private class GetUserResponse implements AsyncCallback<ClientUser> {
		@Override
		public void onFailure(Throwable caught) {
		}

		@Override
		public void onSuccess(ClientUser result) {
			user = result;
			loginbar.setScore(user.getScore());
			loginbar.update("");
		}
	}
	
	private class AddScoreResponse implements AsyncCallback<Boolean> {
		@Override
		public void onFailure(Throwable caught) {
		}

		@Override
		public void onSuccess(Boolean result) {
			
			if (result.booleanValue()) {
				SERVICE.getUser(
						sessionID,
						new GetUserResponse());
			} else {
				
			}
		}
	}
}
